from typing import Dict, Any, List, AsyncGenerator

from langchain_core.messages import HumanMessage, AIMessage
from langgraph.graph import StateGraph
from langgraph.graph.state import CompiledStateGraph
from langgraph.prebuilt import create_react_agent

from AIAgents.streamableAgent import StreamableAgent
from config.logging_config import get_logger
from utils.loggerUtils import LoggerUtils

# 使用全局日志配置系统
logger = get_logger(__name__)


class ReActAgent(StreamableAgent):
    """ReAct Agent实现，使用LangGraph的create_react_agent，集成记忆管理"""

    def __init__(self, **kwargs):
        # 先设置必要的属性，避免属性访问错误
        self.react_agent = None
        self._creation_error = None

        # 然后初始化基础组件
        super().__init__(**kwargs)

        # 创建 ReAct Agent
        self._create_react_agent()

        # 记录初始化状态
        self.log_component_status()

        # ReAct Agent 特定的状态检查
        logger.info("🤖 ReAct Agent 特定状态:")
        logger.info(f"   - ReAct Agent: {'创建成功' if self.react_agent else '创建失败'}")
        if self._creation_error:
            logger.error(f"   - 错误信息: {self._creation_error}")

    def _create_react_agent(self):
        """创建ReAct Agent，使用baseAgent的工具和系统提示词"""
        try:
            if not self.llm:
                self._creation_error = "LLM未配置，无法创建ReAct Agent"
                logger.error(f"❌ {self._creation_error}")
                return

            # 使用已创建的工具列表（来自baseAgent的全局工具字典）
            all_tools = self.tools if self.tools else []
            logger.info(f"🔧 准备创建ReAct Agent，可用工具: {len(all_tools)}")

            # 为每个工具记录详细信息
            for i, tool in enumerate(all_tools):
                logger.info(f"   {i + 1}. {tool.name}: {getattr(tool, 'description', '无描述')[:50]}...")

            # 创建增强的系统提示词
            system_prompt = self._create_enhanced_system_prompt()

            # 使用create_react_agent创建agent
            self.react_agent = create_react_agent(
                model=self.llm,
                tools=all_tools,
                prompt=system_prompt
            )

            # 更新graph属性以保持兼容性
            if self.react_agent:
                self.graph = self.react_agent
                logger.info("✅ ReAct Agent创建成功")
                self._creation_error = None
            else:
                self._creation_error = "create_react_agent返回了None"
                logger.error(f"❌ {self._creation_error}")

        except Exception as e:
            self._creation_error = f"创建ReAct Agent失败: {str(e)}"
            logger.error(f"❌ {self._creation_error}")
            LoggerUtils.log_error(self._creation_error, e, logger)

    def _prepare_input_with_memory(self, input_text: str) -> Dict[str, Any]:
        """
        使用baseAgent的记忆工作流准备输入
        """
        try:
            # 使用baseAgent的智能记忆工作流
            memory_result = self.process_intelligent_memory_workflow(input_text)

            if memory_result.get("success", False):
                # 转换为ReAct Agent期望的消息格式
                history = memory_result.get("history", [])
                messages = []

                # 转换历史消息为LangChain格式
                for msg in history[-10:]:  # 取最近10条
                    role = msg.get("role", "")
                    content = msg.get("content", "")

                    if role == "user" and content:
                        messages.append(HumanMessage(content=content))
                    elif role == "assistant" and content:
                        messages.append(AIMessage(content=content))

                # 添加当前用户输入
                messages.append(HumanMessage(content=input_text))

                logger.info(f"🧠 使用记忆增强输入，消息数: {len(messages)} (历史: {len(history)})")
                return {"messages": messages}
            else:
                logger.warning(f"记忆工作流失败，使用基础输入: {memory_result.get('error')}")

        except Exception as e:
            logger.warning(f"准备记忆输入失败: {e}")

        # 回退到简单输入
        return {"messages": [HumanMessage(content=input_text)]}

    async def process_stream(self, input_data: Dict[str, Any]) -> AsyncGenerator[Dict[str, Any], None]:
        """流式处理输入并返回结果，集成记忆管理"""
        try:
            input_text = input_data.get("input", "")
            LoggerUtils.log_agent_start("ReActAgent", input_text, logger)

            # 基础检查
            if not input_text.strip():
                yield await self._yield_error_message("输入内容不能为空")
                return

            if not self.react_agent:
                error_msg = self._creation_error or "ReAct Agent未正确初始化"
                yield await self._yield_error_message(error_msg)
                return

            # 发送开始处理消息
            yield await self._yield_thinking_message("ReAct Agent开始分析问题和工具...", "start")

            try:
                # 准备包含记忆上下文的输入
                initial_state = self._prepare_input_with_memory(input_text)

                # 处理流式输出
                collected_messages = []
                final_response = ""
                tool_calls_summary = {
                    'total_calls': 0,
                    'details': []
                }

                async for chunk in self.react_agent.astream(initial_state, stream_mode="updates"):
                    try:
                        for node_name, update in chunk.items():
                            logger.debug(f"收到节点更新: {node_name}")

                            if "messages" in update and update["messages"]:
                                for message in update["messages"]:
                                    content = self._extract_message_content(message)
                                    collected_messages.append(message)

                                    # 识别工具调用
                                    if hasattr(message, 'tool_calls') and message.tool_calls:
                                        tool_calls_summary['total_calls'] += len(message.tool_calls)
                                        for tool_call in message.tool_calls:
                                            tool_calls_summary['details'].append({
                                                'name': tool_call.get('name', '未知工具'),
                                                'args': tool_call.get('args', {})
                                            })

                                        yield await self._yield_thinking_message(
                                            f"正在调用工具: {', '.join([tc.get('name', '未知') for tc in message.tool_calls])}",
                                            "tool_execution"
                                        )

                                    # 流式输出消息内容
                                    if content and content.strip():
                                        final_response = content
                                        yield {
                                            "type": "stream",
                                            "content": content,
                                            "partial": True,
                                            "metadata": {
                                                "node": node_name,
                                                "agent": "ReActAgent"
                                            }
                                        }

                    except Exception as chunk_error:
                        logger.warning(f"处理流式块失败: {chunk_error}")
                        continue

                # 保存对话到记忆
                if final_response and self.memory_manager:
                    try:
                        self._add_conversation_to_memory(input_text, final_response)
                        logger.info("✅ 对话已保存到记忆系统")
                    except Exception as memory_error:
                        logger.warning(f"保存记忆失败: {memory_error}")

                # 发送最终结果
                yield await self._yield_final_result(
                    success=bool(final_response),
                    response=final_response or "无法生成有效回答",
                )

            except Exception as processing_error:
                logger.error(f"ReAct处理流程发生错误: {processing_error}")
                yield await self._yield_error_message(f"处理过程中发生错误: {str(processing_error)}")

        except Exception as e:
            LoggerUtils.log_error(f"ReActAgent流式处理失败: {str(e)}", e, logger)
            yield await self._yield_error_message(f"系统错误: {str(e)}")

    def _extract_message_content(self, message) -> str:
        """提取消息内容"""
        try:
            if hasattr(message, 'content'):
                return str(message.content) if message.content else ""
            return str(message) if message else ""
        except Exception as e:
            logger.warning(f"提取消息内容失败: {e}")
            return ""

    def _build_graph(self) -> Any:
        """构建Agent的工作流图 - ReActAgent使用create_react_agent，不需要自己构建图"""
        return self.react_agent

    def _define_edges(self, workflow: StateGraph) -> List[tuple]:
        """定义节点之间的连接关系 - ReActAgent使用create_react_agent，不需要手动定义"""
        return []

    def _define_nodes(self, workflow: StateGraph) -> Dict[str, Any]:
        """定义工作流中的节点 - ReActAgent使用create_react_agent，不需要手动定义"""
        return {}

    def process(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
        """处理输入数据并返回结果 - ReActAgent使用流式处理，不支持同步处理"""
        return {
            "success": False,
            "error": "ReActAgent不支持同步处理，请使用process_stream方法",
            "message": "请使用process_stream方法进行流式处理"
        }
